#include "tju_tcp.h"

/*
创建 TCP socket 
初始化对应的结构体
设置初始状态为 CLOSED
*/
tju_tcp_t* tju_socket(){

    //初始化event log
    init_log();

    //更改超时信号的处理函数
    signal(SIGALRM, timeout_handler);

    tju_tcp_t* sock = (tju_tcp_t*)malloc(sizeof(tju_tcp_t));
    sock->state = CLOSED;
    
    //初始化发送和接收缓冲区
    pthread_mutex_init(&(sock->send_lock), NULL);
    sock->sending_buf = NULL;
    sock->sending_len = 0;
    sock->have_send_len = 0;

    pthread_mutex_init(&(sock->recv_lock), NULL);
    sock->received_buf = NULL;
    sock->received_len = 0;
    
    //初始化条件变量(recv函数)
    if(pthread_cond_init(&sock->wait_cond, NULL) != 0){
        perror("ERROR condition variable not set\n");
        exit(-1);
    }

    //初始化发送窗口
    sock->window.wnd_send = (sender_window_t*)malloc(sizeof(sender_window_t));
    sock->window.wnd_send->window_size = MAX_DLEN;
    sock->window.wnd_send->ack_cnt = 0;
    sock->window.wnd_send->base = 1;
    sock->window.wnd_send->nextseq = 1;
    sock->window.wnd_send->same_ack_cnt = 0;
    sock->window.wnd_send->estmated_rtt = TCP_RTO_MIN;
    sock->window.wnd_send->dev_rtt = 0;
    sock->window.wnd_send->is_estimating_rtt = FALSE;
    sock->window.wnd_send->rtt_expect_ack = 0;
    sock->window.wnd_send->timeout.it_value.tv_sec = 0;
    sock->window.wnd_send->timeout.it_value.tv_usec = 500000;
    sock->window.wnd_send->timeout.it_interval.tv_sec = 0;
    sock->window.wnd_send->timeout.it_interval.tv_usec = 0;
    sock->window.wnd_send->window_status = SLOW_START;
    sock->window.wnd_send->rwnd = MAX_RWINDOW_SIZE;
    sock->window.wnd_send->cwnd = MAX_DLEN;
    sock->window.wnd_send->ssthresh = MAX_SWINDOW_SIZE >> 1;

    //初始化接收窗口
    sock->window.wnd_recv = (receiver_window_t*)malloc(sizeof(receiver_window_t));
    sock->window.wnd_recv->remain_size = MAX_RWINDOW_SIZE;
    sock->window.wnd_recv->recv_buf = (char*)malloc(MAX_RWINDOW_SIZE);
    sock->window.wnd_recv->mark = (uint8_t*)malloc(MAX_RWINDOW_SIZE);
    memset(sock->window.wnd_recv->mark, 0, MAX_RWINDOW_SIZE);
    sock->window.wnd_recv->expect_seq = 1;
    
    //初始化其他变量
    sock->is_retransing = 0;
    sock->seq = 0; 
    sock->ack = 0;

    return sock;
}

/*
绑定监听的地址 包括ip和端口
*/
int tju_bind(tju_tcp_t* sock, tju_sock_addr bind_addr){
    if(bind_port[bind_addr.port] != 0){
        perror("ERROR bind port already in use\n");
        exit(-1);
    }
    sock->bind_addr = bind_addr;
    bind_port[bind_addr.port] = 1;
    return 0;
}

/*
被动打开 监听bind的地址和端口
设置socket的状态为LISTEN
注册该socket到内核的监听socket哈希表
*/
int tju_listen(tju_tcp_t* sock){
    sock->state = LISTEN;
    int hashval = cal_hash(sock->bind_addr.ip, sock->bind_addr.port, 0, 0);
    listen_socks[hashval] = sock;
    sock->half_queue = init_q();
    sock->full_queue = init_q();

    return 0;
}

/*
接受连接 
返回与客户端通信用的socket
这里返回的socket一定是已经完成3次握手建立了连接的socket
因为只要该函数返回, 用户就可以马上使用该socket进行send和recv
*/
tju_tcp_t* tju_accept(tju_tcp_t* listen_sock){
    while(!listen_sock->full_queue->size);
    printf("全连接队列中有新的连接\n");
    tju_tcp_t* new_conn = (tju_tcp_t*)malloc(sizeof(tju_tcp_t));
    new_conn = pop_q(listen_sock->full_queue);


    //创建发送线程
    pthread_t sending_thread_id;
    int rst1 = pthread_create(&sending_thread_id, NULL, sending_thread, (void*)new_conn);
    if(rst1 < 0){
        perror("ERROR create sending thread\n");
        exit(-1);
    }
    printf("sending thread 创建成功\n");

    //创建重传线程
    pthread_t retrans_thread_id;
    int rst2 = pthread_create(&retrans_thread_id, NULL, retrans_thread, (void*)new_conn);
    if(rst2 < 0){
        perror("ERROR create retrans thread\n");
        exit(-1);
    }
    printf("retrans thread 创建成功\n");

    // 如果new_conn的创建过程放到了tju_handle_packet中 那么accept怎么拿到这个new_conn呢
    // 在linux中 每个listen socket都维护一个已经完成连接的socket队列
    // 每次调用accept 实际上就是取出这个队列中的一个元素
    // 队列为空,则阻塞 
    return new_conn;
}


/*
连接到服务端
该函数以一个socket为参数
调用函数前, 该socket还未建立连接
函数正常返回后, 该socket一定是已经完成了3次握手, 建立了连接
因为只要该函数返回, 用户就可以马上使用该socket进行send和recv
*/
int tju_connect(tju_tcp_t* sock, tju_sock_addr target_addr){

    sock->established_remote_addr = target_addr;

    tju_sock_addr local_addr;
    local_addr.ip = inet_network(CLIENT_IP);
    local_addr.port = 5678; // 连接方进行connect连接的时候 内核中是随机分配一个可用的端口
    sock->established_local_addr = local_addr;

    // 发送一个SYN报文给服务端
    char* syn_pkt = create_packet_buf(local_addr.port, target_addr.port, 0, 0, \
                                            DEFAULT_HEADER_LEN, DEFAULT_HEADER_LEN, \
                                            SYN_FLAG_MASK, 1, 0, NULL, 0);
    sendToLayer3(syn_pkt, DEFAULT_HEADER_LEN);
    _SEND_LOG_(syn_pkt);
    //状态更新
    sock->state = SYN_SENT;
    sock->seq++;

    // 将建立了连接的socket放入内核 已建立连接哈希表中
    int hashval = cal_hash(local_addr.ip, local_addr.port, target_addr.ip, target_addr.port);
    established_socks[hashval] = sock;

    //启动重传计时器
    clock_t timer = clock(); 
    while(sock->state!= ESTABLISHED){ // 阻塞
        if(clock() - timer > 5000000){
            sendToLayer3(syn_pkt, DEFAULT_HEADER_LEN);
            _SEND_LOG_(syn_pkt);
            printf("客户端重传SYN包\n");
            timer = clock();
        }
    }
    free(syn_pkt);


    //创建发送线程
    pthread_t sending_thread_id;
    int rst1 = pthread_create(&sending_thread_id, NULL, sending_thread, (void*)sock);
    if(rst1 < 0){
        perror("ERROR create sending thread\n");
        exit(-1);
    }
    printf("sending thread 创建成功\n");

    //创建重传线程
    pthread_t retrans_thread_id;
    int rst2 = pthread_create(&retrans_thread_id, NULL, retrans_thread, (void*)sock);
    if(rst2 < 0){
        perror("ERROR create retrans thread\n");
        exit(-1);
    }
    printf("retrans thread 创建成功\n");

    return 0;
}

int tju_send(tju_tcp_t* sock, const void *buffer, int len){
    char* tmp_buffer = (char*) buffer;
    int tmp_len = len;
    while((sock->sending_len < MAX_SOCK_BUF_SIZE) || tmp_len){// 当发送长度已经到最大容量或者还有剩余的数据没有拷贝
        if(MAX_SOCK_BUF_SIZE - sock->sending_len == 0) continue;
        pthread_mutex_lock(&(sock->send_lock));
        if(MAX_SOCK_BUF_SIZE - sock->sending_len >= tmp_len){
            // 剩余空间足够 直接拷贝
            memcpy(sock->sending_buf + sock->sending_len, tmp_buffer, tmp_len);
            sock->sending_len += tmp_len;
            pthread_mutex_unlock(&(sock->send_lock));
            break;
        }else{
            memcpy(sock->sending_buf + sock->sending_len, tmp_buffer, MAX_SOCK_BUF_SIZE-sock->sending_len);
            sock->sending_len = MAX_SOCK_BUF_SIZE;
            tmp_buffer += MAX_SOCK_BUF_SIZE-sock->sending_len;
            tmp_len -= MAX_SOCK_BUF_SIZE-sock->sending_len;
            pthread_mutex_unlock(&(sock->send_lock));
        }
    }
    return 0;
}

int tju_recv(tju_tcp_t* sock, void *buffer, int len){
    while(sock->received_len<=0){
        // 阻塞
    }

    while(pthread_mutex_lock(&(sock->recv_lock)) != 0); // 加锁

    int read_len = 0;
    if (sock->received_len >= len){ // 从中读取len长度的数据
        read_len = len;
    }else{
        read_len = sock->received_len; // 读取sock->received_len长度的数据(全读出来)
    }

    memcpy(buffer, sock->received_buf, read_len);

    if(read_len < sock->received_len) { // 还剩下一些
        char* new_buf = malloc(sock->received_len - read_len);
        memcpy(new_buf, sock->received_buf + read_len, sock->received_len - read_len);
        free(sock->received_buf);
        sock->received_len -= read_len;
        sock->received_buf = new_buf;
    }else{
        free(sock->received_buf);
        sock->received_len = 0;
    }
    pthread_mutex_unlock(&(sock->recv_lock)); // 解锁

    return read_len;
}

int tju_handle_packet(tju_tcp_t* sock, char* pkt){
    //socket是内核中维护的socket 不是用户传入的socket

    _RECV_LOG_(pkt);
    uint8_t flags = get_flags(pkt);
    uint32_t ack = get_ack(pkt);
    uint32_t seq = get_seq(pkt);
    uint32_t data_len = get_plen(pkt) - DEFAULT_HEADER_LEN;
    uint16_t src_port = get_src(pkt);
    uint16_t dst_port = get_dst(pkt);
    uint16_t adv_wnd = get_advertised_window(pkt);

    //1.第一次握手 服务器收到SYN报文后 回复SYN+ACK报文
    if(sock->state == LISTEN && (flags & SYN_FLAG_MASK)){

        sock->seq = 0;// 初始化seq为0
        //第二次握手
        char* syn_ack_pkt = create_packet_buf(dst_port, src_port, sock->seq, seq+1,
            DEFAULT_HEADER_LEN, DEFAULT_HEADER_LEN, SYN_FLAG_MASK | ACK_FLAG_MASK,
            1, 0, NULL, 0);
        sendToLayer3(syn_ack_pkt, DEFAULT_HEADER_LEN);
        _SEND_LOG_(syn_ack_pkt);
        free(syn_ack_pkt);
        sock->seq++;
        sock->ack = seq+1;

        //新建socket放入半连接队列,并加入ehash
        tju_tcp_t* new_conn = tju_socket();
        new_conn->established_local_addr = sock->bind_addr;
        new_conn->established_remote_addr.port = src_port;
        new_conn->established_remote_addr.ip = inet_network(CLIENT_IP);
        new_conn->state = SYN_RECV;
        new_conn->seq = sock->seq;
        push_q(sock->half_queue, new_conn);// 放入半连接队列
        // 加入ehash
        int hashval = cal_hash(new_conn->established_local_addr.ip, new_conn->established_local_addr.port, 0, 0);
        established_socks[hashval] = new_conn;

        return 0;
    }

    //2.发送第三次握手 客户端收到SYN+ACK报文后 回复ACK报文
    if(sock->state == SYN_SENT && 
        (flags & (SYN_FLAG_MASK | ACK_FLAG_MASK)) == (SYN_FLAG_MASK | ACK_FLAG_MASK)){
        sock->state = ESTABLISHED;
        char *ack_pkt = create_packet_buf(dst_port, src_port, ack, seq+1,
                                            DEFAULT_HEADER_LEN, DEFAULT_HEADER_LEN, ACK_FLAG_MASK, 1, 0, NULL, 0);
        sendToLayer3(ack_pkt, DEFAULT_HEADER_LEN);
        _SEND_LOG_(ack_pkt);
        free(ack_pkt);
        sock->seq++;
        sock->ack = seq+1;

        return 0;
    }

    //3.收到第三次握手 服务器收到ACK报文后 加入全连接队列
    if(sock->state == SYN_RECV && (flags & ACK_FLAG_MASK)){
        sock->state = ESTABLISHED;
        //加入全连接队列，并从半连接队列中删除
        tju_tcp_t* new_conn = pop_q(sock->half_queue);
        new_conn->state = ESTABLISHED;
        new_conn->seq = sock->seq;
        push_q(sock->full_queue, new_conn);
        return 0;
    }

    //4.server/client收到数据报文
    if(sock->state == ESTABLISHED && (flags == NO_FLAG)){
        if(seq < sock->window.wnd_recv->expect_seq) {// 收到的seq比期待的seq还小，直接发回ack包
            //log
            tju_packet_t* pkt_ack = create_packet(sock->established_local_addr.port, sock->established_remote_addr.port,
                                        sock->window.wnd_send->nextseq, sock->window.wnd_recv->expect_seq, DEFAULT_HEADER_LEN, DEFAULT_HEADER_LEN,
                                        ACK_FLAG_MASK, sock->window.wnd_recv->remain_size, 0, NULL, 0);/* 创建ack包 */
            char* pkt_ack_buf = packet_to_buf(pkt_ack);
            sendToLayer3(pkt_ack_buf, DEFAULT_HEADER_LEN);  // 发送ack包
            _SEND_LOG_(pkt_ack_buf);
            free(pkt_ack_buf);
        }
        else{ // 收到的seq大于等于期待的seq，在可以容忍乱序到达的前提下划分为一类情况
            // 发回ack，窗口滑动，释放已记录的可释放长度
            // sock->window.wnd_send->free_length += data_len;
            // sock->window.wnd_send->base = sock->window.wnd_send->base + sock->window.wnd_send->free_length;
            // sock->window.wnd_send->free_length = 0;
            uint32_t expt_seq = sock->window.wnd_recv->expect_seq; //
            char* recv_buf = sock->window.wnd_recv->recv_buf;
            uint8_t* mark = sock->window.wnd_recv->mark;
            if (seq + data_len < expt_seq + MAX_RWINDOW_SIZE){ // 到达的seq加上数据长度比接收方期待收到的seq加上最大窗口长度小就可以放下
                // 把数据报文的数据拷贝到接收方的接收缓冲区，并将拷贝好的区域mark为1
                memcpy(recv_buf + seq - expt_seq, pkt + get_hlen(pkt), data_len);
                memset(mark + seq - expt_seq, 1, data_len);
            }

            if (mark[0]!=0){ // 发送窗口的第一个字节可以滑动了
                uint16_t free_len = 0;
                while(mark[free_len]!=0){
                    free_len++;
                }
                if (MAX_SOCK_BUF_SIZE - sock->received_len < free_len){
                    // printf("接收缓冲区装不下，丢弃该报文\n");
                    // 更新接收窗口剩余大小
                    sock->window.wnd_recv->remain_size=MAX_RWINDOW_SIZE-free_len;
                }
                else{
                    sock->window.wnd_recv->remain_size=MAX_RWINDOW_SIZE;
                    // 缓冲区能够装下该数据报
                    pthread_mutex_lock(&(sock->recv_lock));     // 加锁
                    memcpy(sock->received_buf + sock->received_len, recv_buf, free_len);
                    sock->received_len += free_len;
                    pthread_mutex_unlock(&(sock->recv_lock)); // 解锁

                    // 更新接收窗口
                    sock->window.wnd_recv->recv_buf = (char *)malloc(MAX_RWINDOW_SIZE);
                    memcpy(sock->window.wnd_recv->recv_buf, recv_buf + free_len, MAX_RWINDOW_SIZE - free_len);
                    free(recv_buf);
                    sock->window.wnd_recv->mark = (uint8_t *)malloc(MAX_RWINDOW_SIZE);
                    memset(sock->window.wnd_recv->mark, 0, MAX_RWINDOW_SIZE);
                    memcpy(sock->window.wnd_recv->mark, mark + free_len, MAX_RWINDOW_SIZE - free_len);
                    free(mark);
                    sock->window.wnd_recv->expect_seq += free_len;
                    _DELV_LOG_(expt_seq,free_len);
                }
            }
            tju_packet_t* pkt_ack = create_packet(sock->established_local_addr.port, sock->established_remote_addr.port,
                                        sock->window.wnd_send->nextseq, sock->window.wnd_recv->expect_seq, DEFAULT_HEADER_LEN, DEFAULT_HEADER_LEN,
                                        ACK_FLAG_MASK, sock->window.wnd_recv->remain_size, 0, NULL, 0);/* 创建ack包 */
            char* pkt_ack_buf = packet_to_buf(pkt_ack);
            sendToLayer3(pkt_ack_buf, DEFAULT_HEADER_LEN);  // 发送ack包
            _SEND_LOG_(pkt_ack_buf);
            free(pkt_ack_buf);
        }
        return 0;
    }
    //4.server/client收到数据报文
    if(sock->state == ESTABLISHED && (flags & ACK_FLAG_MASK)){
        // 根据advertised window值更新发送窗口的大小
        sock->window.wnd_send->rwnd = adv_wnd;
        _RWND_LOG_(sock);
        if(ack < sock->window.wnd_send->base){ // 收到的ACK的ack值比发送窗口的第一个字节都小
            printf("收到的ack报文在发送窗口外 丢弃报文 \n");
            // 更新发送窗口
            sock->window.wnd_send->window_size=min(sock->window.wnd_send->cwnd,sock->window.wnd_send->rwnd);
            _SWND_LOG_(sock);
        }
        else if(ack == sock->window.wnd_send->base){ // 收到的ACK等于发送窗口的第一个字节，相当于重复ACK了,意味着发生了丢包需要重传
            if (sock->window.wnd_send->window_status==SLOW_START||sock->window.wnd_send->window_status==CONGESTION_AVOIDANCE){
                sock->window.wnd_send->same_ack_cnt++;
            }
            // 快速恢复
            else if (sock->window.wnd_send->window_status==FAST_RECOVERY){
                sock->window.wnd_send->cwnd+=MAX_DLEN;
                _CWND_LOG_(sock,FAST_RECOVERY);
            }

            // 连续收到3个重复的ack
            if (sock->window.wnd_send->same_ack_cnt==3&&sock->window.wnd_send->window_status!=FAST_RECOVERY){
                // 拥塞阈值更新为发送窗口的一半
                sock->window.wnd_send->ssthresh=sock->window.wnd_send->cwnd>>1;
                // 当前拥塞窗口更新为拥塞阈值
                sock->window.wnd_send->cwnd=sock->window.wnd_send->ssthresh;
                _CWND_LOG_(sock,FAST_RECOVERY);
                // 更新发送窗口状态为 快速恢复
                sock->window.wnd_send->window_status=FAST_RECOVERY;

                printf("收到三个重复ack，开始快速重传\n");
                // 开启快速重传
                sock->is_retransing = true;
                RETRANS=TRUE;
            }
            // 更新发送窗口
            sock->window.wnd_send->window_size=min(sock->window.wnd_send->cwnd,sock->window.wnd_send->rwnd);
            _SWND_LOG_(sock);
        }
        else { // 收到了正常的ACK
            printf("收到有效ACK报文 ack=%d\n", ack);
            sock->window.wnd_send->same_ack_cnt = 0;  // 刷新快速重传计数

            // 更新拥塞窗口大小、状态
            if (sock->window.wnd_send->window_status==SLOW_START){
                sock->window.wnd_send->cwnd*=2;
                if (sock->window.wnd_send->cwnd>=sock->window.wnd_send->ssthresh){
                    sock->window.wnd_send->cwnd=sock->window.wnd_send->ssthresh;
                    sock->window.wnd_send->window_status=CONGESTION_AVOIDANCE;
                }
                _CWND_LOG_(sock,SLOW_START);
            }
            else if (sock->window.wnd_send->window_status==CONGESTION_AVOIDANCE){
                sock->window.wnd_send->cwnd+=MAX_DLEN;
                _CWND_LOG_(sock,CONGESTION_AVOIDANCE);
            }
            else if (sock->window.wnd_send->window_status==FAST_RECOVERY){
                sock->window.wnd_send->window_status=CONGESTION_AVOIDANCE;
            }

            // 更新发送窗口
            sock->window.wnd_send->window_size=min(sock->window.wnd_send->cwnd,sock->window.wnd_send->rwnd);
            _SWND_LOG_(sock);

            // 开始计算 SampleRTT
            if (sock->window.wnd_send->is_estimating_rtt==TRUE){
                if (sock->window.wnd_send->rtt_expect_ack==ack){
                    CalTimeout(sock);
                }
                sock->window.wnd_send->is_estimating_rtt=FALSE;
            }

            
            // 发送窗口滑动
            sock->window.wnd_send->ack_cnt += ack - sock->window.wnd_send->base;
            sock->window.wnd_send->base = ack;

            // 启动定时器

            if (sock->window.wnd_send->base == sock->window.wnd_send->nextseq){
                // 缓冲区中没有尚未发送的数据
                stopTimer();
                sock->is_retransing=FALSE;
            }
            else{
                // 重新开始计时
                startTimer(sock);
                sock->is_retransing=TRUE;
            }

            // 清理发送缓冲区中已收到确认的数据
            if (sock->sending_len && (sock->window.wnd_send->ack_cnt == sock->sending_len || sock->window.wnd_send->ack_cnt > 4*MAX_SOCK_BUF_SIZE/5))
            {
                printf("正在清理发送缓冲区:\n");
                pthread_mutex_lock(&sock->send_lock);   // 加锁
                char* new_sending_buf=(char *)malloc(MAX_SOCK_BUF_SIZE);
                memcpy(new_sending_buf, sock->sending_buf + sock->window.wnd_send->ack_cnt, sock->sending_len - sock->window.wnd_send->ack_cnt);
                free(sock->sending_buf);
                sock->sending_buf = new_sending_buf;
                sock->sending_len = sock->sending_len - sock->window.wnd_send->ack_cnt;
                sock->have_send_len = sock->have_send_len - sock->window.wnd_send->ack_cnt;
                sock->window.wnd_send->ack_cnt = 0;
                pthread_mutex_unlock(&sock->send_lock);  // 解锁
                printf("清理完毕\n");
            }
            
        }
        if (sock->window.wnd_send->window_size==0){
            
            startTimer(sock);
            sock->is_retransing=FALSE;      // 表示当前为 0 窗口探测阶段
        }
        return 0;
    }

    //5.收到FIN报文 发送FIN+ACK报文
    if(sock->state == ESTABLISHED && (flags & FIN_FLAG_MASK)){
        sock->state = CLOSE_WAIT;
        char* fin_ack_pkt = create_packet_buf(dst_port, src_port, ack, seq+1,
                                            DEFAULT_HEADER_LEN, DEFAULT_HEADER_LEN, FIN_FLAG_MASK | ACK_FLAG_MASK, 1, 0, NULL, 0);
        sendToLayer3(fin_ack_pkt, DEFAULT_HEADER_LEN);
        _SEND_LOG_(fin_ack_pkt);
        free(fin_ack_pkt);
        sock->seq++;
        sock->ack = seq+1;

        return 0;
    }

    //6.单向关闭连接
    if(sock->state == FIN_WAIT_1){
        // 收到ACK报文 进入FIN_WAIT_2
        if((flags & ACK_FLAG_MASK) && !(flags & FIN_FLAG_MASK)){
            sock->state = FIN_WAIT_2;
            return 0;
        }
        else if((flags & (ACK_FLAG_MASK | FIN_FLAG_MASK)) == (ACK_FLAG_MASK | FIN_FLAG_MASK)){
            // 同时收到ACK+FIN报文（双方同时关闭）
            sock->state = CLOSING;

            //发送ACK报文
            char* ack_pkt = create_packet_buf(dst_port, src_port, 122, seq+1,
                                            DEFAULT_HEADER_LEN, DEFAULT_HEADER_LEN, ACK_FLAG_MASK, 1, 0, NULL, 0);
            sendToLayer3(ack_pkt, DEFAULT_HEADER_LEN);
            _SEND_LOG_(ack_pkt);
            free(ack_pkt);
            sock->seq++;
            sock->ack = seq+1;

            return 0;
        }
        else return 0;
    }
     
    //7.在FIN_WAIT_2下 收到FIN报文（第三次挥手）
    if(sock->state == FIN_WAIT_2 && (flags & FIN_FLAG_MASK)){
      //进入TIME_WAIT
      sock->state = TIME_WAIT;
      
      //发送ACK报文
      char* ack_pkt = create_packet_buf(dst_port, src_port, ack, seq+1,
                                            DEFAULT_HEADER_LEN, DEFAULT_HEADER_LEN, ACK_FLAG_MASK, 1, 0, NULL, 0);
      sendToLayer3(ack_pkt, DEFAULT_HEADER_LEN);
      _SEND_LOG_(ack_pkt);
      free(ack_pkt);
      sock->seq++;
      sock->ack = seq+1;

      //等待2MSL后关闭连接
      sleep(6); // 这里假设2MSL是6秒 实际中可以根据需要调整
      sock->state = CLOSED;

      return 0;
    }

    //8.在LAST_ACK下 收到ACK报文（第四次挥手）
    if(sock->state == LAST_ACK && (flags & ACK_FLAG_MASK)){
      //进入CLOSED
      sock->state = CLOSED;
      return 0;
    }

    //9.在CLOSING状态下 收到ACK
    if(sock->state == CLOSING && (flags & ACK_FLAG_MASK)){
        //进入TIME_WAIT
        sock->state = TIME_WAIT;

        //等待2MSL后关闭连接
        sleep(6); // 这里假设2MSL是6秒 实际中可以根据需要调整
        sock->state = CLOSED;
    }
    return 0;
}

int tju_close (tju_tcp_t* sock){
    // 发送第一次挥手
    if(sock->state == ESTABLISHED){
        sock->state = FIN_WAIT_1;
        char* packet = create_packet_buf(sock->established_local_addr.port, sock->established_remote_addr.port, 
        sock->seq, 0, DEFAULT_HEADER_LEN, DEFAULT_HEADER_LEN, FIN_FLAG_MASK, 0, 0, NULL, 0);
        sendToLayer3(packet, DEFAULT_HEADER_LEN);
        _SEND_LOG_(packet);
        free(packet);
        sock->seq++;
        printf("发送了FIN 1\n");

        return 0;
    }

    // 发送第三次挥手
    if(sock->state == CLOSE_WAIT){
        sock->state = LAST_ACK;
        char* packet = create_packet_buf(sock->established_local_addr.port, sock->established_remote_addr.port, 
        sock->seq, 0, DEFAULT_HEADER_LEN, DEFAULT_HEADER_LEN, FIN_FLAG_MASK | ACK_FLAG_MASK, 0, 0, NULL, 0);
        sendToLayer3(packet, DEFAULT_HEADER_LEN);
        printf("发送了FIN 2\n");
        _SEND_LOG_(packet);
        free(packet);
        sock->seq++;

        return 0;
    }
    return 0;
    
}

// 监听socket创建一个新的socket 用于与客户端通信
// tju_tcp_t* create_conn_socket(tju_tcp_t* sock, uint16_t src_port){
//     tju_tcp_t* new_conn = tju_socket();
//     new_conn->state = SYN_RECV;
//     new_conn->seq = sock->seq + 1; 
//     tju_sock_addr remote_addr;
//     remote_addr.ip = inet_network("172.17.0.2");      
//     remote_addr.port = src_port;   
//     new_conn->established_local_addr = sock->bind_addr;    
//     new_conn->established_remote_addr = remote_addr;    
//     int hashval = cal_hash(new_conn->established_local_addr.ip, new_conn->established_local_addr.port, 
//         new_conn->established_remote_addr.ip, new_conn->established_remote_addr.port);
//     established_socks[hashval] = new_conn;
//     return new_conn;
// }